/**
 * 组件：Captcha
 * 作用：产生图形验证码
 * 验证码的工作流程：
 *      a。后端生成验证码（有诸多格式：图片、url、base64等），随后将验证码验证结果存儒道缓存中
 *      b。客户端发起请求，能够取到验证码图片及一个与验证码验证结果相关联的key值
 *      c。图片需要页面上展示。key值需要存储在前端中（最合理的是存储在组件state中）
 *      d。用户输入验证码
 *      e。将用户输入的验证码码值与key值一起发送给服务器
 *      f。服务器将验证码的值与key值与缓存中的数据进行比较，一致则返回成功，否则失败
 *      g。如果成功，则前端允许用户继续下一步操作；否则前端提示用户并且刷新验证码
 * 
 * 细节：
 *      1：点击刷新问题
 *      2：key存放在哪里
 *          可能存在部分场景，在同一个组件显示两次及以上次数需要使用Captcha，容易导致后加载的验证码的key值覆盖之前的验证码的key值
 *      3:验证码如何做到场景通用（尺寸）
 *      4：取消请求发送
 * 
 * 切记  父需要传递一个方法
 * 
 */
import React, { Component } from 'react';
import Pts from "prop-types"
import axios from 'axios';

class Captcha extends Component {
    //默认值
    static defaultProps = {
        h:36,
        w:120
    }

    //数据类型约束
    static propTypes ={
        //针对saveKey提出的类型约束规则，必须要有，且为函数类型
        saveKey:Pts.func.isRequired
    }

    state = {
        url:""
    }

    source = axios.CancelToken.source()

    render() {
        return (
            <div>
                <img src={this.state.url} alt="验证码"  width={this.props.w} height={this.props.h} onClick={this.load} title='点击刷新'/>
                
            </div>
        );
    }

    componentDidMount(){
        this.load()
    }
    load = () =>{
        axios.get("https://reactapi.iynn.cn/captcha/api/math",{
            CancelToken:this.source.token,
            params:{
                //防止低版本IE浏览器的缓存机制,需要用到这个随机数的方法
                t:Math.random()
            }
        }).then(res=>{
            this.setState({
                url:res.data.img
            },()=>this.props.saveKey(res.data.key))
        }).catch(e=>{})//抑制异常显示
    }
    componentWillUnmount(){
        //接触挂载之前销毁请求
        this.source.cancel()
    }
}

export default Captcha;
